from email.header import Header
from email.mime.base import MIMEBase
from email import encoders
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import smtplib
import os
from socket import gaierror, timeout

def send_email(smtp_user, smtp_password, to_email, subject, body, attachment_path):
    try:
        # 构建邮件
        msg = MIMEMultipart()
        msg['From'] = smtp_user
        msg['To'] = to_email
        msg['Subject'] = Header(subject, 'utf-8')  # 对邮件主题进行 UTF-8 编码

        # 添加邮件正文，指定编码为 UTF-8
        msg.attach(MIMEText(body, 'plain', 'utf-8'))

        # 如果存在附件，添加附件
        if os.path.isfile(attachment_path):
            with open(attachment_path, 'rb') as attachment:
                part = MIMEBase('application', 'octet-stream')
                part.set_payload(attachment.read())
                encoders.encode_base64(part)

                # 使用 Header 对文件名进行编码，而不是 RFC 2231 格式
                file_name = os.path.basename(attachment_path)
                part.add_header(
                    'Content-Disposition',
                    'attachment',
                    filename=Header(file_name, 'utf-8').encode()
                )
                msg.attach(part)

        # 连接 SMTP 服务器并发送邮件
        with smtplib.SMTP('smtp.office365.com', 587, timeout=10) as server:
            server.starttls()
            server.login(smtp_user, smtp_password)
            server.send_message(msg)

        return True, None  # 邮件发送成功

    except smtplib.SMTPRecipientsRefused:
        return False, f"收件人地址无效: {to_email}"

    except smtplib.SMTPAuthenticationError:
        return False, "SMTP身份验证失败，请检查您的用户名和密码。"

    except smtplib.SMTPConnectError:
        return False, "无法连接到SMTP服务器，请检查网络连接。"

    except smtplib.SMTPException as e:
        return False, f"SMTP错误: {str(e)},或检查压缩包内是否有大于30MB的文件（或大于您邮箱的最大附件大小)"

    except gaierror:
        return False, "网络问题: 无法解析SMTP服务器地址。"

    except timeout:
        return False, "网络超时: 连接到SMTP服务器超时，请检查网络连接。"

    except Exception as e:
        return False, f"未知错误: {str(e)}"
